﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;
using System.Diagnostics;

namespace Zero.UControl.Demo.Views.UAdorner.Component
{
    public class TransformAdorner : ElementDecoratorBase
    {
        private readonly Thumb _rotateThumb;
        private readonly Thumb _scaleThumb;
        private readonly VisualCollection _visuals;

        private Point _center;
        private double _startAngle;

        public TransformAdorner(UIElement adornedElement) : base(adornedElement)
        {
            _visuals = new VisualCollection(this);

            _rotateThumb = CreateThumb(Brushes.Red, Cursors.Hand);
            _rotateThumb.DragStarted += RotateThumb_DragStarted;
            _rotateThumb.DragDelta += RotateThumb_DragDelta;
            _rotateThumb.DragCompleted += Thumb_DragCompleted;
            _visuals.Add(_rotateThumb);

            _scaleThumb = CreateThumb(Brushes.Blue, Cursors.SizeNWSE);
            _scaleThumb.DragStarted += _scaleThumb_DragStarted;
            _scaleThumb.DragDelta += ScaleThumb_DragDelta;
            _scaleThumb.DragCompleted += Thumb_DragCompleted;
            _visuals.Add(_scaleThumb);
        }

        public override void Attach(UIElement element, Canvas canvas)
        {
            base.Attach(element, canvas);
            CompositionTarget.Rendering += OnRendering;
        }

        public override void Dettach(UIElement element)
        {
            CompositionTarget.Rendering -= OnRendering;
        }

        private Thumb CreateThumb(Brush color, Cursor cursor) => new Thumb
        {
            Width = 10,
            Height = 10,
            Background = color,
            Cursor = cursor,
            BorderBrush = Brushes.White,
            BorderThickness = new Thickness(1)
        };

        private SelectionAdorner cachedSelectionAdorner;
        private void RotateThumb_DragStarted(object sender, DragStartedEventArgs e)
        {
            if (AdornedElement is FrameworkElement fe)
            {
                // 隐藏 SelectionAdorner
                var adornerLayer = AdornerLayer.GetAdornerLayer(fe);
                var selectionAdorner = adornerLayer?.GetAdorners(fe).OfType<SelectionAdorner>().FirstOrDefault();
                if (selectionAdorner != null)
                {
                    selectionAdorner.Visibility = Visibility.Collapsed;
                }

                TransformUtil.EnsureTransformGroup(fe);
                _center = fe.TranslatePoint(new Point(fe.ActualWidth / 2, fe.ActualHeight / 2), this);

                var mousePos = Mouse.GetPosition(this);
                var v = mousePos - _center;
                _startAngle = Math.Atan2(v.Y, v.X) * 180 / Math.PI - 90;
            }
        }

        private void RotateThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            if (AdornedElement is FrameworkElement fe)
            {
                var rotate = TransformUtil.GetRotate(fe);
                var mousePos = Mouse.GetPosition(this);
                _center = fe.TranslatePoint(new Point(fe.ActualWidth / 2, fe.ActualHeight / 2), this);
                var v = mousePos - _center;
                double angle = Math.Atan2(v.Y, v.X) * 180 / Math.PI - 90;

                double delta = angle - _startAngle;
                rotate.Angle += delta;
                _startAngle = angle;
            }
        }

        private void _scaleThumb_DragStarted(object sender, DragStartedEventArgs e)
        {
            if (AdornedElement is FrameworkElement fe)
            {
                // 隐藏 SelectionAdorner
                var adornerLayer = AdornerLayer.GetAdornerLayer(fe);
                var selectionAdorner = adornerLayer?.GetAdorners(fe).OfType<SelectionAdorner>().FirstOrDefault();
                if (selectionAdorner != null)
                {
                    selectionAdorner.Visibility = Visibility.Collapsed;
                }
            }
        }

        private void ScaleThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            if (AdornedElement is FrameworkElement fe)
            {
                TransformUtil.EnsureTransformGroup(fe);
                var scale = TransformUtil.GetScale(fe);

                double delta = Math.Max(e.HorizontalChange, e.VerticalChange) * 0.01;
                scale.ScaleX = Math.Max(0.1, scale.ScaleX + delta);
                scale.ScaleY = Math.Max(0.1, scale.ScaleY + delta);
            }
        }

        private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            if (AdornedElement is FrameworkElement fe)
            {
                // 显示 SelectionAdorner
                var adornerLayer = AdornerLayer.GetAdornerLayer(fe);
                var selectionAdorner = adornerLayer?.GetAdorners(fe).OfType<SelectionAdorner>().FirstOrDefault();
                if (selectionAdorner != null)
                {
                    selectionAdorner.Visibility = Visibility.Visible;
                }
                InvalidateVisual();
            }
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            if (AdornedElement is FrameworkElement fe)
            {
                var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
                var rotateThumbPos = new Point(center.X, -20);
                var scaleThumbPos = new Point(fe.ActualWidth, fe.ActualHeight);

                try
                {
                    var transform = fe.TransformToVisual(this);
                    rotateThumbPos = transform.Transform(rotateThumbPos);
                    scaleThumbPos = transform.Transform(scaleThumbPos);
                }
                catch(Exception ex) 
                {
                    Trace.WriteLine(ex.Message);
                }

                _rotateThumb.Arrange(new Rect(rotateThumbPos.X - 5, rotateThumbPos.Y - 5, 10, 10));
                _scaleThumb.Arrange(new Rect(scaleThumbPos.X - 5, scaleThumbPos.Y - 5, 10, 10));
            }
            return finalSize;
        }

        private void OnRendering(object sender, EventArgs e)
        {
            if (AdornedElement is FrameworkElement fe)
            {
                var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
                var rotateThumbPos = new Point(center.X, -20);
                var scaleThumbPos = new Point(fe.ActualWidth, fe.ActualHeight);

                try
                {
                    // 将坐标点从相对于当前元素的坐标系转换为相对于Adorner的坐标系
                    var transform = fe.TransformToVisual(this);
                    rotateThumbPos = transform.Transform(rotateThumbPos);
                    scaleThumbPos = transform.Transform(scaleThumbPos);
                }
                catch { return; }

                _rotateThumb.Arrange(new Rect(rotateThumbPos.X - 5, rotateThumbPos.Y - 5, 10, 10));
                _scaleThumb.Arrange(new Rect(scaleThumbPos.X - 5, scaleThumbPos.Y - 5, 10, 10));
            }
        }


        protected override int VisualChildrenCount => _visuals.Count;
        protected override Visual GetVisualChild(int index) => _visuals[index];

        ~TransformAdorner()
        {
            CompositionTarget.Rendering -= OnRendering;
        }
    }
}
